//动态数组 Vector 是存储在堆上
fn read(v: Vec<i32>, index: usize) {
    // 使用 & 和 [] 返回一个引用；或者使用 get 方法以索引作为参数来返回一个 Option<&T>。
    match v.get(index) {
        Some(third) => println!("is {}", third),
        None => println!(" None ."),
    }
}

#[cfg(test)]
mod vec_test {
    #[test]
    fn create() {
        let a: [i32; 5] = [1, 2, 3, 4, 5]; //字面量
        let a = [3; 5]; //重复
        let v = vec![1, 2, 3]; //宏

        // 闭包 复杂数据
        let array: [String; 8] = std::array::from_fn(|_i| String::from("rust is good!"));

        let one = [1, 2, 3];
        let two: [u8; 3] = [1, 2, 3];
        let blank1 = [0; 3];
        let blank2: [u8; 3] = [0; 3];
        let arrays: [[u8; 3]; 4] = [one, two, blank1, blank2];

        for a in &arrays {
            print!("{:?}: ", a);
            for n in a.iter() {
                print!("\t{} + 10 = {}", n, n + 10);
            }

            let mut sum = 0;
            for i in 0..a.len() {
                sum += a[i];
            }
            println!("\t({:?} = {})", a, sum);
        }
    }

    #[test]
    fn method() {
        let mut v = Vec::new();
        v.push(11);
        v.push(21);
        v.push(31);
        println!("vec.len: {:?}", v.len());
        println!("vec.remove: {:?}", v.remove(2)); // 移除指定位置的元素并返回, v: [1, 3]
        println!("{:?}", v[1]);
        println!("vec.get: {:?}", v.get(3));
        println!("vec.pop: {:?}", v.pop());

        let mut v = Vec::with_capacity(10); //指定一个实际的预估容量
        v.push(1);
        v.reserve(100); // 调整 v 的容量，至少要有 100 的容量
        v.shrink_to_fit(); // 释放剩余的容量，一般情况下，不会主动去释放容量
        v.insert(2, 3); // 在指定索引插入数据，索引值不能大于 v 的长度， v: [1, 2, 3]
        v.clear(); // 清空 v, v: []

        let mut v1 = [11, 22].to_vec(); // append 操作会导致 v1 清空数据，增加可变声明
        v.append(&mut v1); // 将 v1 中的所有元素附加到 v 中, v1: []
        v.truncate(1); // 截断到指定长度，多余的元素被删除, v: [11]
        v.retain(|x| *x > 10); // 保留满足条件的元素，即删除不满足条件的元素

        let slice = &v[1..=3]; //切片
    }

    #[test]
    fn sort() {
        // 在 rust 里，实现了两种排序算法，分别为稳定的排序 sort 和 sort_by，
        // 以及非稳定排序 sort_unstable 和 sort_unstable_by。

        // 非稳定 指在排序过程中对相等元素的处理方式
        // 非稳定 排序的算法的速度会优于 稳定 排序算法，同时，稳定 排序还会额外分配原数组一半的空间。
        let mut vec = vec![1, 5, 10, 2, 15];
        println!("{:?}", vec);
        vec.sort_unstable();
        println!("{:?}", vec);
        vec.sort();
        println!("{:?}", vec);

        // 在浮点数当中，存在一个 NAN 的值，这个值无法与其他的浮点数进行对比
        // 浮点数类型并没有实现全数值可比较 Ord 的特性，而是实现了部分可比较的特性 PartialOrd。
        let mut vec_f = vec![1.0, 5.6, 10.3, 2.0, 15f32];
        // vec_f.sort_unstable(); //err
        println!("{:?}", vec_f);
        vec_f.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
        println!("{:?}", vec_f);
    }

    #[test]
    fn for_() {
        let v2 = vec![1, 2, 3];
        // v2.iter(); //迭代器

        // for x in v2 {}; //安全高效
        for x in 0..=v2.len() {} //安全高效
    }

    #[derive(Debug)]
    enum IpAddr {
        V4(String),
        V6(String),
    }

    #[test]
    fn store() {
        let v = vec![
            IpAddr::V4("127.0.0.1".to_string()),
            IpAddr::V6("::1".to_string()),
        ];

        for ip in v {
            println!("{:?}", ip);
        }
    }
}

#[cfg(test)]
mod trait_test {
    trait IpAddr {
        fn display(&self);
    }

    struct V4(String);

    impl IpAddr for V4 {
        fn display(&self) {
            println!("ipv4: {:?}", self.0)
        }
    }

    struct V6(String);

    impl IpAddr for V6 {
        fn display(&self) {
            println!("ipv6: {:?}", self.0)
        }
    }

    #[test]
    fn main() {
        let v: Vec<Box<dyn IpAddr>> = vec![
            Box::new(V4("127.0.0.1".to_string())),
            Box::new(V6("::1".to_string())),
        ];

        for ip in v {
            ip.display();
        }
    }
}

#[cfg(test)]
mod sort {
    #[derive(Debug)]
    struct Person {
        name: String,
        age: u32,
    }

    impl Person {
        fn new(name: String, age: u32) -> Person {
            Person { name, age }
        }
    }

    // 实现排序接口--》（可能）支持排序
    // 需要 derive Ord 相关特性，需要确保你的结构体中所有的属性均实现了 Ord 相关特性，否则会发生编译错误。
    #[derive(Debug, Ord, Eq, PartialEq, PartialOrd)]
    struct PersonAll {
        name: String,
        age: u32,
    }

    impl PersonAll {
        fn new(name: String, age: u32) -> PersonAll {
            PersonAll { name, age }
        }
    }

    #[test]
    fn per() {
        let mut people = vec![
            Person::new("Zoe".to_string(), 25),
            Person::new("Al".to_string(), 60),
            Person::new("John".to_string(), 1),
        ];
        // 定义一个按照年龄倒序排序的对比函数
        people.sort_unstable_by(|a, b| b.age.cmp(&a.age));
        println!("{:?}", people);
    }

    #[test]
    fn all() {
        let mut people = vec![
            PersonAll::new("Zoe".to_string(), 25),
            PersonAll::new("Al".to_string(), 60),
            PersonAll::new("Al".to_string(), 30),
            PersonAll::new("John".to_string(), 1),
            PersonAll::new("John".to_string(), 25),
        ];

        people.sort_unstable();
        println!("{:?}", people);
    }
}
